home *** CD-ROM | disk | FTP | other *** search
/ Delphi Informant Complete 1995 - 2000 / Delphi Informant Complete 1995 to 2000.iso / Delphi Informant Magazine Complete Works SOURCE CODE 1998.rar / 1998 / Feb / di9802kw / CGIApp2.pas next >
Pascal/Delphi Source File  |  1997-08-19  |  17KB  |  589 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Delphi Visual Component Library                 }
  5. {       CGI/WinCGI Web server application components    }
  6. {                                                       }
  7. {       Copyright (c) 1997 Borland International        }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit CGIApp2;
  12.  
  13. interface
  14.  
  15. uses Windows, Classes, HTTPApp, IniFiles;
  16.  
  17. type
  18.   TCGIRequest = class(TWebRequest)
  19.   private
  20.     FContent: string;
  21.   protected
  22.     function GetStringVariable(Index: Integer): string; override;
  23.     function GetDateVariable(Index: Integer): TDateTime; override;
  24.     function GetIntegerVariable(Index: Integer): Integer; override;
  25.   public
  26.     constructor Create;
  27.     function GetFieldByName(const Name: string): string; override;
  28.     function ReadClient(var Buffer; Count: Integer): Integer; override;
  29.     function ReadString(Count: Integer): string; override;
  30.     function TranslateURI(const URI: string): string; override;
  31.     function WriteClient(var Buffer; Count: Integer): Integer; override;
  32.     function WriteString(const AString: string): Boolean; override;
  33.   end;
  34.  
  35.   TCGIResponse = class(TWebResponse)
  36.   private
  37.     FStatusCode: Integer;
  38.     FStringVariables: array[0..MAX_STRINGS - 1] of string;
  39.     FIntegerVariables: array[0..MAX_INTEGERS - 1] of Integer;
  40.     FDateVariables: array[0..MAX_DATETIMES - 1] of TDateTime;
  41.     FContent: string;
  42.     FSent: Boolean;
  43.   protected
  44.     function GetContent: string; override;
  45.     function GetDateVariable(Index: Integer): TDateTime; override;
  46.     function GetIntegerVariable(Index: Integer): Integer; override;
  47.     function GetLogMessage: string; override;
  48.     function GetStatusCode: Integer; override;
  49.     function GetStringVariable(Index: Integer): string; override;
  50.     function Sent: Boolean; override;
  51.     procedure SetContent(const Value: string); override;
  52.     procedure SetDateVariable(Index: Integer; const Value: TDateTime); override;
  53.     procedure SetIntegerVariable(Index: Integer; Value: Integer); override;
  54.     procedure SetLogMessage(const Value: string); override;
  55.     procedure SetStatusCode(Value: Integer); override;
  56.     procedure SetStringVariable(Index: Integer; const Value: string); override;
  57.   public
  58.     constructor Create(HTTPRequest: TWebRequest);
  59.     procedure SendResponse; override;
  60.     procedure SendRedirect(const URI: string); override;
  61.     procedure SendStream(AStream: TStream); override;
  62.   end;
  63.  
  64.   TWinCGIRequest = class(TCGIRequest)
  65.   private
  66.     FIniFile: TIniFile;
  67.     FClientData, FServerData: TFileStream;
  68.   protected
  69.     function GetStringVariable(Index: Integer): string; override;
  70.   public
  71.     constructor Create(IniFileName, ContentFile, OutputFile: string);
  72.     destructor Destroy; override;
  73.     function GetFieldByName(const Name: string): string; override;
  74.     function ReadClient(var Buffer; Count: Integer): Integer; override;
  75.     function ReadString(Count: Integer): string; override;
  76.     function TranslateURI(const URI: string): string; override;
  77.     function WriteClient(var Buffer; Count: Integer): Integer; override;
  78.     function WriteString(const AString: string): Boolean; override;
  79.   end;
  80.  
  81.   TWinCGIResponse = class(TCGIResponse);
  82.  
  83.   TCGIApplication = class(TWebApplication)
  84.   private
  85.     FOutputFileName: string;
  86.     function NewRequest: TCGIRequest;
  87.     function NewResponse(CGIRequest: TCGIRequest): TCGIResponse;
  88.   public
  89.     procedure Run; override;
  90.   end;
  91.  
  92. implementation
  93.  
  94. uses SysUtils, WebConst;
  95.  
  96. const
  97.   CGIServerVariables: array[0..28] of string = (
  98.     'REQUEST_METHOD',
  99.     'SERVER_PROTOCOL',
  100.     'URL',
  101.     'QUERY_STRING',
  102.     'PATH_INFO',
  103.     'PATH_TRANSLATED',
  104.     'HTTP_CACHE_CONTROL',
  105.     'HTTP_DATE',
  106.     'HTTP_ACCEPT',
  107.     'HTTP_FROM',
  108.     'HTTP_HOST',
  109.     'HTTP_IF_MODIFIED_SINCE',
  110.     'HTTP_REFERER',
  111.     'HTTP_USER_AGENT',
  112.     'HTTP_CONTENT_ENCODING',
  113.     'HTTP_CONTENT_TYPE',
  114.     'HTTP_CONTENT_LENGTH',
  115.     'HTTP_CONTENT_VERSION',
  116.     'HTTP_DERIVED_FROM',
  117.     'HTTP_EXPIRES',
  118.     'HTTP_TITLE',
  119.     'REMOTE_ADDR',
  120.     'REMOTE_HOST',
  121.     'SCRIPT_NAME',
  122.     'SERVER_PORT',
  123.     '',
  124.     'HTTP_CONNECTION',
  125.     'HTTP_COOKIE',
  126.     'HTTP_AUTHORIZATION');
  127.  
  128. { TCGIRequest }
  129.  
  130. constructor TCGIRequest.Create;
  131. begin
  132.   inherited Create;
  133.   FContent := ReadString(ContentLength);
  134. end;
  135.  
  136. function TCGIRequest.GetFieldByName(const Name: string): string;
  137. var
  138.   Buffer: array[0..4095] of Char;
  139.  
  140.   function StripHTTP(const Name: string): string;
  141.   begin
  142.     if Pos('HTTP_', Name) = 1 then
  143.       Result := Copy(Name, 6, MaxInt)
  144.     else Result := Name;
  145.   end;
  146.  
  147. begin
  148.   SetString(Result, Buffer, GetEnvironmentVariable(PChar(Name), Buffer, SizeOf(Buffer)));
  149.   if Result = '' then
  150.     SetString(Result, Buffer, GetEnvironmentVariable(PChar(StripHTTP(Name)), Buffer, SizeOf(Buffer)));
  151. end;
  152.  
  153. function TCGIRequest.GetStringVariable(Index: Integer): string;
  154. begin
  155.   if Index = 25 then
  156.     Result := FContent
  157.   else Result := GetFieldByName(CGIServerVariables[Index]);
  158. end;
  159.  
  160. function TCGIRequest.GetDateVariable(Index: Integer): TDateTime;
  161. var
  162.   Value: string;
  163. begin
  164.   Value := GetStringVariable(Index);
  165.   if Value <> '' then
  166.     Result := ParseDate(Value)
  167.   else Result := -1;
  168. end;
  169.  
  170. function TCGIRequest.GetIntegerVariable(Index: Integer): Integer;
  171. var
  172.   Value: string;
  173. begin
  174.   Value := GetStringVariable(Index);
  175.   Result := StrToIntDef(Value, -1)
  176. end;
  177.  
  178. function TCGIRequest.ReadClient(var Buffer; Count: Integer): Integer;
  179. begin
  180.   Result := FileRead(TTextRec(Input).Handle, Buffer, Count);
  181. end;
  182.  
  183. function TCGIRequest.ReadString(Count: Integer): string;
  184. begin
  185.   SetLength(Result, Count);
  186.   if Count > 0 then
  187.     FileRead(TTextRec(Input).Handle, Pointer(Result)^, Count);
  188. end;
  189.  
  190. function TCGIRequest.TranslateURI(const URI: string): string;
  191. begin
  192. end;
  193.  
  194. function TCGIRequest.WriteClient(var Buffer; Count: Integer): Integer;
  195. begin
  196.   Result := FileWrite(TTextRec(Output).Handle, Buffer, Count);
  197. end;
  198.  
  199. function TCGIRequest.WriteString(const AString: string): Boolean;
  200. begin
  201.   if AString <> '' then
  202.     Result := FileWrite(TTextRec(Output).Handle, Pointer(AString)^, Length(AString)) = Length(AString)
  203.   else Result := False;
  204. end;
  205.  
  206. { TCGIResponse }
  207.  
  208. constructor TCGIResponse.Create(HTTPRequest: TWebRequest);
  209. begin
  210.   inherited Create(HTTPRequest);
  211.   if FHTTPRequest.ProtocolVersion = '' then
  212.     Version := '1.0';
  213.   StatusCode := 200;
  214.   LastModified := -1;
  215.   Expires := -1;
  216.   Date := -1;
  217.   ContentType := 'text/html';
  218. end;
  219.  
  220. function TCGIResponse.GetContent: string;
  221. begin
  222.   Result := FContent;
  223. end;
  224.  
  225. function TCGIResponse.GetDateVariable(Index: Integer): TDateTime;
  226. begin
  227.   if (Index >= 0) and (Index < 3) then
  228.     Result := FDateVariables[Index]
  229.   else Result := -1;
  230. end;
  231.  
  232. function TCGIResponse.GetIntegerVariable(Index: Integer): Integer;
  233. begin
  234.   if (Index >= 0) and (Index < 2) then
  235.     Result := FIntegerVariables[Index]
  236.   else Result := -1;
  237. end;
  238.  
  239. function TCGIResponse.GetLogMessage: string;
  240. begin
  241. //  Result := TCGIRequest(HTTPRequest).ECB.lpszLogData;
  242. end;
  243.  
  244. function TCGIResponse.GetStatusCode: Integer;
  245. begin
  246.   Result := FStatusCode;
  247. end;
  248.  
  249. function TCGIResponse.GetStringVariable(Index: Integer): string;
  250. begin
  251.   if (Index >= 0) and (Index < 12) then
  252.     Result := FStringVariables[Index];
  253. end;
  254.  
  255. function TCGIResponse.Sent: Boolean;
  256. begin
  257.   Result := FSent;
  258. end;
  259.  
  260. procedure TCGIResponse.SetContent(const Value: string);
  261. begin
  262.   FContent := Value;
  263.   ContentLength := Length(FContent);
  264. end;
  265.  
  266. procedure TCGIResponse.SetDateVariable(Index: Integer; const Value: TDateTime);
  267. begin
  268.   if (Index >= Low(FDateVariables)) and (Index <= High(FDateVariables)) then
  269.     if Value <> FDateVariables[Index] then
  270.       FDateVariables[Index] := Value;
  271. end;
  272.  
  273. procedure TCGIResponse.SetIntegerVariable(Index: Integer; Value: Integer);
  274. begin
  275.   if (Index >= Low(FIntegerVariables)) and (Index <= High(FIntegerVariables)) then
  276.     if Value <>